package alipushclient

import (
	"encoding/json"
	"fmt"
	"reflect"
)

type PayLoad struct {
	AndroidNotification *AndroidNotice
	IOSNotification     *IOSNotice
	AndroidMessage      interface{}
	IOSMessage          interface{}
}

func NewPushPayLoad() *PayLoad {
	pl := &PayLoad{}
	return pl
}

func (this *PayLoad) SetAndroidNotice(notice *AndroidNotice) {
	this.AndroidNotification = notice
}

func (this *PayLoad) SetIOSNotice(notice *IOSNotice) {
	this.IOSNotification = notice
}

func (this *PayLoad) SetAndroidMessage(m *AndroidMessage) {
	this.AndroidMessage = m
}

func (this *PayLoad) SetIOSMessage(m *IOSMessage) {
	this.IOSMessage = m
}

func (this *PayLoad) AndroidNoticeToBytes(region, accessKeyID, accessKeySecret string) ([]byte, error) {
	req := NewRequestSet()

	public := PublicParameters{}
	public.SetPublicParameters(region, accessKeyID)

	t1 := reflect.TypeOf(public)
	v1 := reflect.ValueOf(public)
	for i := 0; i < t1.NumField(); i++ {
		f1 := t1.Field(i)
		req.Add(f1.Name, v1.Field(i).String())
	}

	t2 := reflect.TypeOf(*(this.AndroidNotification))
	v2 := reflect.ValueOf(*(this.AndroidNotification))
	for i := 0; i < t2.NumField(); i++ {
		f2 := t2.Field(i)
		if "AndroidExtParameters" == f2.Name {

			bytes, _ := json.Marshal(this.AndroidNotification.AndroidExtParameters)
			req.Add(f2.Name, string(bytes))
		} else {
			req.Add(f2.Name, v2.Field(i).String())
		}
	}

	req.Add("Signature", req.Sign(req.GetStringToSign(), accessKeySecret))

	content := []byte("?" + req.Concatenate())

	return content, nil
}

func (this *PayLoad) IOSNoticeToBytes(region, accessKeyID, accessKeySecret string) ([]byte, error) {
	req := NewRequestSet()

	public := PublicParameters{}
	public.SetPublicParameters(region, accessKeyID)

	t1 := reflect.TypeOf(public)
	v1 := reflect.ValueOf(public)
	for i := 0; i < t1.NumField(); i++ {
		f1 := t1.Field(i)
		req.Add(f1.Name, v1.Field(i).String())
	}

	t2 := reflect.TypeOf(*(this.IOSNotification))
	v2 := reflect.ValueOf(*(this.IOSNotification))
	for i := 0; i < t2.NumField(); i++ {
		f2 := t2.Field(i)
		if "IOSExtParameters" == f2.Name {
			bytes, _ := json.Marshal(this.IOSNotification.IOSExtParameters)
			req.Add(f2.Name, string(bytes))
		} else {
			req.Add(f2.Name, v2.Field(i).String())
		}
	}

	req.Add("Signature", req.Sign(req.GetStringToSign(), accessKeySecret))

	content := []byte("?" + req.Concatenate())

	fmt.Printf("%s\r\n", content)

	return content, nil
}

func (this *PayLoad) AndroidMessageToBytes() ([]byte, error) {
	content, err := json.Marshal(this.AndroidMessage)
	if err != nil {
		return nil, err
	}
	return content, nil
}

func (this *PayLoad) IOSMessageToBytes() ([]byte, error) {
	content, err := json.Marshal(this.IOSMessage)
	if err != nil {
		return nil, err
	}
	return content, nil
}
